iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
Software Development

用Canvas打造自己的遊樂場系列 第 22

[Day22]用Canvas打造自己的遊樂場-分裂球 開工

  • 分享至 

  • xImage
  •  

第二個遊戲花的時間比我預期的長,剩下幾天的時間我想來完成一個走迷宮的遊戲.不過在正式開始前,我想先花一點時間來做一個算不上遊戲,但我蠻歡的小程式.記憶中,以前的螢幕保護程式中,有那種很多球一直亂跑,可能會掉進畫面上的黑洞之類的畫面,以前我總是會花很多時間盯著那畫面瞧.
我想要做一個類似的小程式,但我的構想是這樣的,起始畫面上只會有一顆球,當球碰到牆壁反彈時,球會分裂,畫面中最多800顆球.
其實也就是一個小小的程式,但他會用到之後要寫的迷宮會用到的一些東西,就順便完成一下吧.
那首先先把前面的程式整理一下,留下可能會用到的程式.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Second Game</title>
    <meta name="description" content="第三個遊戲">
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
</head>

<body>
    <canvas id="playground" width="800" height="600"></canvas>
    <script>

        window.onload = () => {
            canvas = document.getElementById('playground');
            canvasContext = canvas.getContext('2d');

            //一秒更新幾次畫面
            var timesPerSec = 30;
            setInterval(drawAll, 1000 / timesPerSec);
        }

        // 負責更新畫面
        drawAll = () => {
            move();
            draw();
        }

        // 負責畫畫
        draw = () => {
            // background
            drawRectangle(0, 0, canvas.width, canvas.height, 'black');
        }

        // 負責處理動作
        move = () => {

        }

        // 矩形元件
        drawRectangle = (topLeftX, topLeftY, boxWidth, boxHeight, color) => {
            canvasContext.fillStyle = color;
            canvasContext.fillRect(topLeftX, topLeftY, boxWidth, boxHeight);
        }

        // 圓形元件
        drawCircle = (centerX, centerY, r, color) => {
            canvasContext.fillStyle = color;
            canvasContext.beginPath();
            canvasContext.arc(centerX, centerY, r, 0, Math.PI * 2);
            canvasContext.fill();
        }

        // 畫線
        drawLine = (beginX, beginY, endX, endY, color) => {
            canvasContext.strokeStyle = color;
            canvasContext.beginPath();
            canvasContext.moveTo(beginX, beginY);
            canvasContext.lineTo(endX, endY);
            canvasContext.stroke();
        }

        // 畫生命
        drawLife = (lifeX, lifeY, size, color) => {
            canvasContext.fillStyle = color;
            canvasContext.beginPath();
            canvasContext.arc(lifeX + size / 4, lifeY + size / 4, size / 4, Math.PI * 1, Math.PI * 0);
            canvasContext.arc(lifeX + size * 3 / 4, lifeY + size / 4, size / 4, Math.PI * 1, Math.PI * 0);
            canvasContext.moveTo(lifeX + size, lifeY + size / 4);
            canvasContext.lineTo(lifeX + size / 2, lifeY + size);
            canvasContext.lineTo(lifeX, lifeY + size / 4);
            canvasContext.fill();
        }

        // 畫出生命
        showLife = (num) => {
            for (let life_count = 0; life_count < num; life_count++) {
                drawLife(LIFE_SIZE * life_count, 0, LIFE_SIZE, 'red');
            }
        }

    </script>
</body>

</html>

我們這邊把畫面改成800600,那今天要完成的內容是畫出球撞到會反彈的牆壁.這邊每塊磚的設定為4040,那畫面最多就會有20*15塊磚,這邊還不是要畫較複雜的迷宮,所以就不用一下畫太精細.

// 地圖設定
const MAP_BRICKS = 40;
const BRICK_SPACING = 1;
const BRICK_COLS = 20;
const BRICK_ROWS = 15;

var map = [
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
    1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
];

這邊來寫個畫地圖的function

// 畫地圖
drawMap = () => {
    for(var col = 0; col < BRICK_COLS; col++) {
        for(var row = 0; row < BRICK_ROWS; row++) {
            if(mapBrick(col, row)) {
                var brickX = col * MAP_BRICKS;
                var brickY = row * MAP_BRICKS;
                drawRectangle(brickX, brickY, MAP_BRICKS - BRICK_SPACING, MAP_BRICKS - BRICK_SPACING, 'gray');
            }
        }
    }
}

brickToIndex = (col, row) => {
    return (col + BRICK_COLS*row);
}

mapBrick = (col, row) => {
    var index = brickToIndex(col, row);
    return (map[index] == 1);
}

然後加入呈現畫面

// 負責畫畫
draw = () => {
    // background
    drawRectangle(0, 0, canvas.width, canvas.height, 'black');

    // 畫地圖
    drawMap();
}

好的,執行看看,畫面應該可以正常執行了.


上一篇
[Day21]用Canvas打造自己的遊樂場-Galaxian 收尾
下一篇
[Day23]用Canvas打造自己的遊樂場-分裂球 球
系列文
用Canvas打造自己的遊樂場30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言